using System;
using System.Reflection;

// Define two interfaces for testing
internal interface IBookRetailer : IDisposable {
   void Purchase();
   void ApplyDiscount();
}

internal interface IMusicRetailer {
   void Purchase();
}


// This class implements 2 interfaces defined by this assembly and 1 interface defined by another assembly
internal sealed class MyRetailer : IBookRetailer, IMusicRetailer, IDisposable {
   // IBookRetailer methods
   void IBookRetailer.Purchase() { }
   public void ApplyDiscount() { }

   // IMusicRetailer method
   void IMusicRetailer.Purchase() { }

   // IDisposable method
   public void Dispose() { }

   // MyRetailer method (not an interface method)
   public void Purchase() { }
}


public sealed class Program {
   public static void Main() {
      // Find interfaces implemented by MyRetailer where the 
      // interface is defined in our own assembly. This is
      // accomplished using a delegate to a filter method
      // that we create and pass to FindInterfaces.
      Type t = typeof(MyRetailer);
      Type[] interfaces = t.FindInterfaces(TypeFilter, 
         typeof(Program).Assembly);
      Console.WriteLine("MyRetailer implements the following " +
         "interfaces (defined in this assembly):");

      // Show information about each interface
      foreach (Type i in interfaces) {
         Console.WriteLine("\nInterface: " + i);

         // Get the type methods that map to the interface's methods
         InterfaceMapping map = t.GetInterfaceMap(i);

         for (Int32 m = 0; m < map.InterfaceMethods.Length; m++) {
            // Display the interface method name and which 
            // type method implements the interface method.
            Console.WriteLine("   {0} is implemented by {1}",
               map.InterfaceMethods[m], map.TargetMethods[m]);
         }
      }
   }


   // Returns true if type matches filter criteria
   private static Boolean TypeFilter(Type t, Object filterCriteria) {
      // Return true if the interface is defined in the same 
      // assembly identified by filterCriteria
      return t.Assembly == filterCriteria;
   }
}